﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.SharePoint;
using WoltersKluwer.SPChainGang.Core.Data.Entity;
using WoltersKluwer.SPChainGang.Core.ExtensionMethods;
using WoltersKluwer.SPChainGang.Core.Util;

namespace WoltersKluwer.SPChainGang.Core.Data.Repository
{
    internal abstract class RepositoryBase<T> : IDisposable where T : BaseEntity
    {
        protected readonly ListResolver listResolver;

        protected RepositoryBase(String siteUrl, string listName)
        {
            listResolver = new ListResolver(siteUrl, listName);
        }

        protected RepositoryBase(SPWeb web, string listName)
        {
            listResolver = new ListResolver(web, listName);
        }

        protected RepositoryBase(SPWeb web, Guid listid)
        {
            listResolver = new ListResolver(web, listid);
        }

        protected virtual T Map(SPListItem item)
        {
            return (T)FastObjectFactory.CreateObject(typeof(T), item);
        }

        protected virtual SPListItem PopulateItem(T entity)
        {
            return entity.Item;
        }

        public SPListItem GetItemById(int id)
        {
            return listResolver.List.GetItemById(id);
        }

        public T GetById(int id)
        {
            return Map(GetItemById(id));
        }

        public void Update(T entity)
        {
            var item = PopulateItem(entity);
            item.Update();
        }

        public void Dispose()
        {
            if (listResolver != null)
                listResolver.Dispose();
        }

        protected virtual List<T> GetItemsWithQuery(string queryText)
        {
            var result = new List<T>();
            var query = new SPQuery
            {
                Query = queryText

            };
            var items = listResolver.List.GetItems(query);
            if (!items.IsNullOrEmpty())
            {
                result = new List<T>(items.Count);
                result.AddRange((from SPListItem d in items select Map(d)).ToList());
            }

            return result;
        }

        protected List<T> GetAllItems()
        {
            return (from SPListItem item in listResolver.List.Items select Map(item)).ToList();
        }
    }
}
